package org.dbpt.performance;

import java.util.ArrayList;
import java.util.List;

public class MeasureHolder extends ArrayList<MeasureSnapshot>{

	private static final long serialVersionUID = 7599358388151788872L;
	
	private DBPTItem rootItem;
	
	public DBPTItem getRootItem() {
		return rootItem;
	}

	public void setRootItem(DBPTItem rootItem) {
		scanAndSet(this.rootItem, null);
		this.rootItem = rootItem;
		scanAndSet(this.rootItem, this);
	}

	protected void scanAndSet(DBPTItem item, MeasureHolder measureHolder) {
		if(item instanceof MeasureSwitcher) {
			MeasureSwitcher measureSwitcher = (MeasureSwitcher) item;
			measureSwitcher.setMeasureHolder(measureHolder);
		}
		if(item instanceof ContainerItem) {
			ContainerItem containerItem = (ContainerItem) item;
			for(DBPTItem child : containerItem.getChildren()) {
				scanAndSet(child, measureHolder);
			}
		}
	}

	public void fixMeasure(MeasureSwitcher measureSwitcher) {
		MeasureSnapshot snapshot = new MeasureSnapshot();
		fixMeasure(rootItem, snapshot, measureSwitcher, false);
		//add(snapshot);
		
	}
	
	protected void fixMeasure(DBPTItem item, MeasureSnapshot snapshot, MeasureSwitcher measureSwitcher, boolean switcherFound) {
		if(measureSwitcher == item) {
			switcherFound = true;
		}
		if(item instanceof MeasureProvider) {
			MeasureProvider measureProvider = (MeasureProvider) item;
			if(measureProvider.getMeasureName() != null && measureProvider.getMeasureValue() != null) {
				snapshot.put(measureProvider.getMeasureName(), measureProvider.getMeasureValue());
				if(!contains(snapshot) && switcherFound) {
					add(snapshot);
				}
			}
		}
		if(item instanceof ContainerItem) {
			ContainerItem containerItem = (ContainerItem) item;
			for(DBPTItem child : containerItem.getChildren()) {
				MeasureSnapshot newSnapshot = (MeasureSnapshot) snapshot.clone();
				fixMeasure(child, newSnapshot, measureSwitcher, switcherFound);
				if(newSnapshot.size() > snapshot.size()) {
					remove(snapshot);
				}
			}
		}
	}

	@Override
	public String toString() {
		List<String> fields = new ArrayList<String>();
		for(MeasureSnapshot snapshot : this) {
			for(String attrName : snapshot.keySet()) {
				if(!fields.contains(attrName)) {
					fields.add(attrName);
				}
			}
		}
		StringBuffer sb = new StringBuffer();
		boolean isFirst = true;
		for(String attrName : fields) {
			if(!isFirst) {
				sb.append(";");
			} else {
				isFirst = false;
			}
			sb.append(attrName);
		}
		sb.append("\n");
		for(MeasureSnapshot snapshot : this) {
			isFirst = true;
			for(String attrName : fields) {
				if(!isFirst) {
					sb.append(";");
				} else {
					isFirst = false;
				}
				Object value = snapshot.get(attrName);
				String sValue = value == null ? "" : value.toString();
				sb.append(sValue);
			}
			sb.append("\n");
		}
		return sb.toString();
	}
	
	
}
